#!/usr/bin/env cargo run
//! 简单的Nacos功能测试工具
//! 
//! 使用方法:
//! cargo run --bin simple_test

use std::sync::Arc;
use anyhow::Result;
use std::io::{self, Write};

use nacos_core::ServiceInstance;
use nacos_core::traits::{NamingService, ConfigService};
use nacos_naming::NamingServiceImpl;
use nacos_config::ConfigServiceImpl;
use nacos_storage::memory::{MemoryServiceStorage, MemoryConfigStorage};

// 简单的EventPublisher实现
#[derive(Debug)]
pub struct SimpleEventPublisher;

#[async_trait::async_trait]
impl nacos_core::EventPublisher for SimpleEventPublisher {
    async fn publish(&self, _event: nacos_core::Event) -> nacos_core::Result<()> {
        Ok(())
    }
    
    async fn subscribe(&self, _listener: Box<dyn nacos_core::EventListener>) -> nacos_core::Result<()> {
        Ok(())
    }
    
    async fn unsubscribe(&self, _listener_name: &str) -> nacos_core::Result<()> {
        Ok(())
    }
}

// Mock 网络服务
#[derive(Debug)]
struct MockNetworkService;

#[async_trait::async_trait]
impl nacos_core::traits::NetworkService for MockNetworkService {
    async fn send_request(
        &self, 
        _node: &nacos_core::ClusterNode, 
        _request: &nacos_core::traits::NetworkRequest
    ) -> nacos_core::Result<nacos_core::traits::NetworkResponse> {
        Ok(nacos_core::traits::NetworkResponse::default())
    }

    async fn broadcast(
        &self, 
        _request: &nacos_core::traits::NetworkRequest
    ) -> nacos_core::Result<Vec<nacos_core::traits::NetworkResponse>> {
        Ok(vec![])
    }

    async fn connect(&self, _node: &nacos_core::ClusterNode) -> nacos_core::Result<()> {
        Ok(())
    }

    async fn disconnect(&self, _node: &nacos_core::ClusterNode) -> nacos_core::Result<()> {
        Ok(())
    }

    async fn is_connected(&self, _node: &nacos_core::ClusterNode) -> nacos_core::Result<bool> {
        Ok(true)
    }
}

// 测试上下文
struct TestContext {
    naming_service: NamingServiceImpl,
    config_service: ConfigServiceImpl,
}

impl TestContext {
    async fn new() -> Result<Self> {
        // 创建服务
        let service_storage = Arc::new(MemoryServiceStorage::new());
        let config_storage = Arc::new(MemoryConfigStorage::new());
        let event_publisher = Arc::new(SimpleEventPublisher);
        let network_service = Arc::new(MockNetworkService);
        
        let naming_service = NamingServiceImpl::new(
            service_storage,
            event_publisher.clone(),
            network_service,
        );
        
        let config_service = ConfigServiceImpl::new(config_storage, event_publisher);
        
        // 启动服务
        naming_service.start().await?;
        config_service.start().await?;
        
        Ok(Self {
            naming_service,
            config_service,
        })
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    println!("🚀 Nacos Rust 交互式测试工具");
    println!("========================================");
    
    let ctx = TestContext::new().await?;
    println!("✅ Nacos服务初始化完成");
    
    loop {
        print_menu();
        
        let choice = read_input("请选择操作 (0-7): ")?;
        
        match choice.trim() {
            "0" => {
                println!("👋 退出测试工具");
                break;
            },
            "1" => test_register_service(&ctx).await?,
            "2" => test_discover_service(&ctx).await?,
            "3" => test_heartbeat(&ctx).await?,
            "4" => test_publish_config(&ctx).await?,
            "5" => test_get_config(&ctx).await?,
            "6" => test_list_configs(&ctx).await?,
            "7" => demo_scenario(&ctx).await?,
            _ => println!("❌ 无效选择，请重新输入"),
        }
        
        println!();
    }
    
    Ok(())
}

fn print_menu() {
    println!("\n📋 可用操作:");
    println!("  1. 注册服务实例");
    println!("  2. 发现服务");
    println!("  3. 发送心跳");
    println!("  4. 发布配置");
    println!("  5. 获取配置");
    println!("  6. 列出所有配置");
    println!("  7. 演示完整场景");
    println!("  0. 退出");
    println!("{}", "-".repeat(40));
}

fn read_input(prompt: &str) -> Result<String> {
    print!("{}", prompt);
    io::stdout().flush()?;
    
    let mut input = String::new();
    io::stdin().read_line(&mut input)?;
    Ok(input)
}

async fn test_register_service(ctx: &TestContext) -> Result<()> {
    println!("\n🔧 注册服务实例");
    
    let service_name = read_input("服务名 (默认: test-service): ")?
        .trim().to_string();
    let service_name = if service_name.is_empty() { "test-service".to_string() } else { service_name };
    
    let ip = read_input("IP地址 (默认: 127.0.0.1): ")?
        .trim().to_string();
    let ip = if ip.is_empty() { "127.0.0.1".to_string() } else { ip };
    
    let port_str = read_input("端口 (默认: 8080): ")?;
    let port: u16 = port_str.trim().parse().unwrap_or(8080);
    
    let mut instance = ServiceInstance::new(
        service_name.clone(),
        "DEFAULT_GROUP".to_string(),
        ip.clone(),
        port,
    );
    instance.namespace = "public".to_string();
    instance.healthy = true;
    instance.weight = 1.0;
    
    ctx.naming_service.register_instance(&instance).await?;
    
    println!("✅ 成功注册服务实例:");
    println!("   服务名: {}", service_name);
    println!("   地址: {}:{}", ip, port);
    println!("   实例ID: {}", instance.instance_id);
    
    Ok(())
}

async fn test_discover_service(ctx: &TestContext) -> Result<()> {
    println!("\n🔍 发现服务");
    
    let service_name = read_input("服务名 (默认: test-service): ")?
        .trim().to_string();
    let service_name = if service_name.is_empty() { "test-service".to_string() } else { service_name };
    
    let instances = ctx.naming_service
        .get_healthy_instances("public", "DEFAULT_GROUP", &service_name)
        .await?;
    
    if instances.is_empty() {
        println!("❌ 未发现服务实例: {}", service_name);
    } else {
        println!("✅ 发现 {} 个服务实例:", instances.len());
        for (i, instance) in instances.iter().enumerate() {
            println!("   实例 {}: {}:{} (权重: {}, 健康: {})", 
                i + 1, 
                instance.ip, 
                instance.port,
                instance.weight,
                instance.healthy
            );
        }
    }
    
    Ok(())
}

async fn test_heartbeat(ctx: &TestContext) -> Result<()> {
    println!("\n💓 发送心跳");
    
    let service_name = read_input("服务名 (默认: test-service): ")?
        .trim().to_string();
    let service_name = if service_name.is_empty() { "test-service".to_string() } else { service_name };
    
    let instance_id = read_input("实例ID: ")?.trim().to_string();
    
    if instance_id.is_empty() {
        println!("❌ 实例ID不能为空");
        return Ok(());
    }
    
    match ctx.naming_service.handle_heartbeat(
        "public", 
        "DEFAULT_GROUP", 
        &service_name, 
        &instance_id
    ).await {
        Ok(_) => println!("✅ 心跳发送成功"),
        Err(e) => println!("❌ 心跳发送失败: {}", e),
    }
    
    Ok(())
}

async fn test_publish_config(ctx: &TestContext) -> Result<()> {
    println!("\n📝 发布配置");
    
    let data_id = read_input("配置ID (默认: test-config): ")?
        .trim().to_string();
    let data_id = if data_id.is_empty() { "test-config".to_string() } else { data_id };
    
    let group = read_input("配置分组 (默认: DEFAULT_GROUP): ")?
        .trim().to_string();
    let group = if group.is_empty() { "DEFAULT_GROUP".to_string() } else { group };
    
    println!("请输入配置内容 (按回车结束):");
    let content = read_input("")?.trim().to_string();
    
    if content.is_empty() {
        println!("❌ 配置内容不能为空");
        return Ok(());
    }
    
    let success = ctx.config_service.publish_config(
        "public",
        &group,
        &data_id,
        &content
    ).await?;
    
    if success {
        println!("✅ 配置发布成功:");
        println!("   配置ID: {}", data_id);
        println!("   分组: {}", group);
        println!("   内容: {}", content);
    } else {
        println!("❌ 配置发布失败");
    }
    
    Ok(())
}

async fn test_get_config(ctx: &TestContext) -> Result<()> {
    println!("\n📖 获取配置");
    
    let data_id = read_input("配置ID (默认: test-config): ")?
        .trim().to_string();
    let data_id = if data_id.is_empty() { "test-config".to_string() } else { data_id };
    
    let group = read_input("配置分组 (默认: DEFAULT_GROUP): ")?
        .trim().to_string();
    let group = if group.is_empty() { "DEFAULT_GROUP".to_string() } else { group };
    
    match ctx.config_service.get_config("public", &group, &data_id).await? {
        Some(content) => {
            println!("✅ 获取配置成功:");
            println!("   配置ID: {}", data_id);
            println!("   分组: {}", group);
            println!("   内容: {}", content);
            
            // 获取配置详情
            if let Some(detail) = ctx.config_service.get_config_detail("public", &group, &data_id).await? {
                println!("   版本: {}", detail.version);
                println!("   MD5: {}", detail.md5);
            }
        },
        None => {
            println!("❌ 配置不存在: {}/{}", group, data_id);
        }
    }
    
    Ok(())
}

async fn test_list_configs(ctx: &TestContext) -> Result<()> {
    println!("\n📋 列出所有配置");
    
    let group = read_input("配置分组 (默认: 全部分组): ")?
        .trim().to_string();
    let group = if group.is_empty() { None } else { Some(group.as_str()) };
    
    let configs = ctx.config_service.list_configs("public", group).await?;
    
    if configs.is_empty() {
        println!("❌ 未找到任何配置");
    } else {
        println!("✅ 找到 {} 个配置:", configs.len());
        for (i, config) in configs.iter().enumerate() {
            println!("   {}. ID: {}, 分组: {}, 版本: {}", 
                i + 1,
                config.data_id,
                config.group,
                config.version
            );
        }
    }
    
    Ok(())
}

async fn demo_scenario(ctx: &TestContext) -> Result<()> {
    println!("\n🎬 演示完整场景");
    println!("模拟电商系统微服务部署...");
    
    // 1. 注册用户服务
    let mut user_service = ServiceInstance::new(
        "user-service".to_string(),
        "production".to_string(),
        "192.168.1.10".to_string(),
        8080,
    );
    user_service.namespace = "public".to_string();
    user_service.healthy = true;
    user_service.weight = 1.0;
    
    ctx.naming_service.register_instance(&user_service).await?;
    println!("✅ 注册用户服务: {}:{}", user_service.ip, user_service.port);
    
    // 2. 注册订单服务
    let mut order_service = ServiceInstance::new(
        "order-service".to_string(),
        "production".to_string(),
        "192.168.1.20".to_string(),
        8080,
    );
    order_service.namespace = "public".to_string();
    order_service.healthy = true;
    order_service.weight = 2.0;
    
    ctx.naming_service.register_instance(&order_service).await?;
    println!("✅ 注册订单服务: {}:{}", order_service.ip, order_service.port);
    
    // 3. 发布数据库配置
    ctx.config_service.publish_config(
        "public",
        "database",
        "user-db",
        r#"{"host":"mysql-user.internal","port":3306,"database":"users"}"#
    ).await?;
    println!("✅ 发布用户数据库配置");
    
    ctx.config_service.publish_config(
        "public",
        "database",
        "order-db",
        r#"{"host":"mysql-order.internal","port":3306,"database":"orders"}"#
    ).await?;
    println!("✅ 发布订单数据库配置");
    
    // 4. 服务发现
    let user_instances = ctx.naming_service
        .get_healthy_instances("public", "production", "user-service")
        .await?;
    println!("✅ 发现用户服务实例: {} 个", user_instances.len());
    
    let order_instances = ctx.naming_service
        .get_healthy_instances("public", "production", "order-service")
        .await?;
    println!("✅ 发现订单服务实例: {} 个", order_instances.len());
    
    // 5. 配置获取
    let user_db_config = ctx.config_service
        .get_config("public", "database", "user-db")
        .await?;
    println!("✅ 获取用户数据库配置: {}", user_db_config.is_some());
    
    // 6. 心跳发送
    ctx.naming_service.handle_heartbeat(
        "public",
        "production",
        "user-service",
        &user_service.instance_id
    ).await?;
    println!("✅ 用户服务心跳发送成功");
    
    println!("\n🎉 演示场景完成!");
    println!("微服务架构部署成功，包含:");
    println!("   - 2个服务 (用户服务、订单服务)");
    println!("   - 2个配置 (用户数据库、订单数据库)");
    println!("   - 服务发现和心跳机制正常工作");
    
    Ok(())
}